﻿//---------------------------------------------------------------------------------
//  This file is part of eRobots Laboratory at Monterrey Institue of Technology.
//
//  Developer: Jesús Salvador Cepeda Barrera.
//
//  Objective: Provide a platform for Behavior-based Pioneer robot Control.
//---------------------------------------------------------------------------------

using Microsoft.Dss.Core.Attributes;

using System;
using System.Collections.Generic;
using System.ComponentModel;

using sicklrf = Microsoft.Robotics.Services.Sensors.SickLRF.Proxy;
using drive = Microsoft.Robotics.Services.Drive.Proxy;
using core = Microsoft.Robotics.Services.MobileRobots.Arcos.Proxy;

namespace PioneerControl
{
    [DataContract]
    public class State
    {
        #region private fields
        private string _remotecmd;
        private int _behcount;
        private int _taskcount;
        private int _rvelocity;
        private int _lvelocity;
        private int _ID;
        private int _batt;
        private double _newHeading;
        private double _currHeading;
        private double _Xpos;
        private double _Ypos;
        private double _velocity;
        private bool _isEnabled;
        private bool _isMoving;
        private bool _ingoal;
        private core.StallAndBumpers _stallbumpers;
        private drive.DriveDifferentialTwoWheelState _drivestate;
        private core.ArcosCoreState _coreState;
        private BehaviorState _behaviorstate;
        private Task _task;
        private TaskStatus _taskstatus;
        private GlobalStatus _globalstatus;
        private Role _role;
        private ActiveBehavior _activebehavior;

        private DateTime _mostRecentLaser = DateTime.Now;

        #endregion

        #region data members
        //THIS MEMBER WAS USED ONLY FOR COMMUNICATION TESTS
        [DataMember]
        [Description("Defined for communication tests.")]
        public string RemoteCommand
        {
            get { return _remotecmd; }
            set { _remotecmd = value; }
        }

        [DataMember]
        [Description("Defined for identifying from other robots; it is constant defined in Start().")]
        public int ID
        {
            get { return _ID; }
            set { _ID = value; }
        }

        [DataMember]
        [Description("The last known state of the core.")]
        public core.ArcosCoreState CoreState
        {
            get { return _coreState; }
            set { _coreState = value; }
        }

        [DataMember]
        [Description("Identifies a given flag for Stall and Bumpers perceptions.")]
        public core.StallAndBumpers StallBumpers
        {
            get { return _stallbumpers; }
            set { _stallbumpers = value; }
        }

        [DataMember(IsRequired = false)]
        [Description("The last known state of the drive.")]
        public drive.DriveDifferentialTwoWheelState DriveState
        {
            get { return _drivestate; }
            set { _drivestate = value; }
        }

        [DataMember]
        [Description("Identifies the time steps using the same behavior.")]
        public int BehaviorCount
        {
            get { return _behcount; }
            set { _behcount = value; }
        }

        [DataMember]
        [Description("Identifies the time steps within the same task.")]
        public int TaskCount
        {
            get { return _taskcount; }
            set { _taskcount = value; }
        }

        [DataMember]
        [Description("Identifies the current battery level.")]
        public int Battery
        {
            get { return _batt; }
            set { _batt = value; }
        }

        [DataMember]
        [Description("Identifies the active behavior state of the robot.")]
        public BehaviorState BehaviorState
        {
            get { return _behaviorstate; }
            set { _behaviorstate = value; }
        }

        [DataMember]
        [Description("Identifies the active behavior of the robot.")]
        public ActiveBehavior ActiveBehavior
        {
            get { return _activebehavior; }
            set { _activebehavior = value; }
        }

        [DataMember]
        [Description("Identifies the active role of the robot.")]
        public Role Role
        {
            get { return _role; }
            set { _role = value; }
        }

        [DataMember]
        [Description("Identifies the status of the robot.")]
        public GlobalStatus GlobalStatus
        {
            get { return _globalstatus; }
            set { _globalstatus = value; }
        }

        [DataMember]
        [Description("Identifies the task's status being developed by the robot.")]
        public TaskStatus TaskStatus
        {
            get { return _taskstatus; }
            set { _taskstatus = value; }
        }

        [DataMember]
        [Description("Identifies the task being addressed the robot.")]
        public Task Task
        {
            get { return _task; }
            set { _task = value; }
        }

        [DataMember]
        [Description("Identifies the new heading set for the drive.")]
        public double NewHeading
        {
            get { return _newHeading; }
            set { _newHeading = value; }
        }

        [DataMember]
        [Description("Identifies the current heading of the robot.")]
        public double Heading
        {
            get { return _currHeading; }
            set { _currHeading = value; }
        }

        [DataMember]
        [Description("Identifies the X coordinate from robot's position")]
        public double Xpos
        {
            get { return _Xpos; }
            set { _Xpos = value; }
        }

        [DataMember]
        [Description("Identifies the Y coordinate from robot's position")]
        public double Ypos
        {
            get { return _Ypos; }
            set { _Ypos = value; }
        }

        [DataMember]
        [Description("Identifies the velocity set for the drive.")]
        public double Velocity
        {
            get { return _velocity; }
            set { _velocity = value; }
        }

        [DataMember]
        [Description("Identifies the right wheel velocity set for the drive.")]
        public int RVelocity
        {
            get { return _rvelocity; }
            set { _rvelocity = value; }
        }

        [DataMember]
        [Description("Identifies the right wheel velocity set for the drive.")]
        public int LVelocity
        {
            get { return _lvelocity; }
            set { _lvelocity = value; }
        }

        [DataMember]
        [Description("Identifies if the robot is moving")]
        public bool IsMoving
        {
            get { return _isMoving; }
            set { _isMoving = value; }
        }

        [DataMember]
        [Description("Identifies if the robot is moving")]
        public bool DriveIsEnabled
        {
            get { return _isEnabled; }
            set { _isEnabled = value; }
        }

        [DataMember]
        [Description("Identifies the time of the most recent laser reading.")]
        public DateTime MostRecentLaser
        {
            get { return _mostRecentLaser; }
            set { _mostRecentLaser = value; }
        }

        [DataMember]
        [Description("Identifies if the robot is in a given homing goal")]
        public bool InGoal
        {
            get { return _ingoal; }
            set { _ingoal = value; }
        }
        #endregion

        #region Monitors

        //internal bool IsUnknown
        //{
        //    get
        //    {
        //        return BehaviorState == BehaviorState.Unknown;
        //    }
        //}

        #endregion
    }

    #region State Variables

    /// <summary>
    /// LIST OF THE ELIGIBLE TASKS
    /// This can be useful for the FANOUT metric, substracting 'score' each time unknown is active.
    /// </summary>
    [DataContract]
    public enum Task
    {
        Unknown,
        EM,
        RI,
        SR
    }

    /// <summary>
    /// LIST OF THE TASKS' STATUS
    /// This can be useful for the metrics TASK TIME DEVELOPMENT in collaboration with Data Member TaskCountdown
    /// </summary>
    [DataContract]
    public enum TaskStatus
    {
        Unknown,
        Halted,
        InProcess,
        NeedHelp,

    }

    /// <summary>
    /// LIST OF THE ELIGIBLE GLOBAL STATUS
    /// </summary>
    [DataContract]
    public enum GlobalStatus
    {
        Unknown,
        Busy,
        Idle,
        Helping
    }

    /// <summary>
    /// LIST OF THE ELIGIBLE ROLES
    /// </summary>
    [DataContract]
    public enum Role
    {
        Unknown,
        FireBrigade,            //For damage control and civilian support
        AmbulanceTeam,          //For civilian transport, relief and support
        PoliceForce,            //Clearing blockades, mapping, exploring
        Malfunction,            //Notifying a physical problem i.e. not moving with speed != 0.
        Rescuer,                //Aid kin by pushing or going towards,
        Trapped,                //Asking help
        Normal                  //Idle Robot
    }

    /// <summary>
    /// LIST OF STATES FOR THE FSM
    /// </summary>
    [DataContract]
    public enum BehaviorState
    {
        Unknown,            //0          Dummy
        AdjustHeading,      //2     BA - Turn Specific Direction i.e. : LargeLeft, MediumRight, SmallRight...
        FreeForwards,       //3     SE - Go Straight
        Disperse,           //8     BA - Go far from the actual direction(s)
        WallFollow,         //9     BA - Wall following
        Approach,           //10    BA - Approaching to some attractor
        Pursue,             //11    BA - Pursuing some moving attractor
        RoadFollow,         //12    BA - Path folloiwing
        Homing,             //13    BA - Backing to home position
        EnterOpenSpace,     //14    SE - Go Forward
        AvoidCollision,      //15    SE - Avoiding an obstacle
        Ready
    }

    /// <summary>
    /// LIST OF THE ELIGIBLE BEHAVIORS
    /// </summary>
    [DataContract]
    public enum ActiveBehavior
    {
        Unknown,
        WakeUp,
        Wait,
        Transport,
        Lost,
        LocateX,
        DriveTowardsX,
        HandleCollision,
        AvoidRobot,
        AvoidObstacle,
        SafeWander,
        Homing,
        BoundaryFollow,
        Disperse,
        Aggregate,
        Forage,
        Flock,
        Impatient,
        Acquiescent,
        Report,
        LowBattery,
        InspectX,
        VictimDetected,
        ThreatDetected,
        RFIDDetected,
        Escape,
        TrackX,
        AvoidPast,
        UnitCenterLine,
        UnitCenterColumn,
        UnitCenterWedge,
        UnitCenterDiamond,
        HoldFormation
    }
    #endregion

}
